package com.xbongbong.sys.model.impl;


import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.sys.domain.dao.CompanyConfigDao;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 公司配置信息
 *
 * @author wufeng
 * @date 2019/1/9 15:21
 * @descption 公司配置信息
 * @return
 */
@Service("companyConfigModel")
public class CompanyConfigModelImpl implements CompanyConfigModel {

    @Resource
    private CompanyConfigDao companyConfigDao;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    @Override
    public Integer insert(CompanyConfigEntity entity) {
        long now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        return companyConfigDao.insert(entity);
    }

    @Override
    public void insertBatch(List<CompanyConfigEntity> lists) {
        companyConfigDao.insertBatch(lists);
    }

    @Override
    public Integer save(CompanyConfigEntity entity) {
        if(entity.getId() == null || Objects.equals(0L, entity.getId())) {
            return insert(entity);
        }
        return update(entity);
    }

    @Override
    public void save(String corpid, String configAlias, String name, String configValue){
        CompanyConfigEntity companyConfig = getConfigEntity(corpid, configAlias);
        if(companyConfig == null){
            companyConfig = new CompanyConfigEntity(corpid, name, configAlias, configValue);
        }else{
            companyConfig.setConfigValue(configValue);
            companyConfig.setUpdateTime(DateTimeUtil.getInt());
        }
        save(companyConfig);
    }

    @Override
    public Integer update(CompanyConfigEntity entity) {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);
        return companyConfigDao.update(entity);
    }

    @Override
    public Long deleteByKey(Long key, String corpid) {
        return companyConfigDao.deleteByKey(key, corpid);
    }

    @Override
    public CompanyConfigEntity getByKey(Long key, String corpid) {
        return companyConfigDao.getByKey(key, corpid);
    }


    @Override
    public CompanyConfigEntity getByConfigName(String configName, String corpid) {
        return companyConfigDao.getByConfigName(configName, corpid);
    }

    @Override
    public CompanyConfigEntity getByConfigAlias(String configAlias, String corpid) {
        return companyConfigDao.getByConfigAlias(configAlias, corpid);
    }


    @Override
    public String getByConfigAlias(String configAlias, String prefix, String key, String corpid, Integer time) {
        String value = paasRedisHelper.getValue(prefix, key);
        if (StringUtil.isEmpty(value)) {
            CompanyConfigEntity companyConfigEntity = getByConfigAlias(configAlias, corpid);
            if (Objects.nonNull(companyConfigEntity)) {
                paasRedisHelper.setValue(prefix, key, companyConfigEntity.getConfigValue(), time);
                return companyConfigEntity.getConfigValue();
            }
        }
        return value;
    }

    @Override
    public String getByConfigAlias(String configAlias, String prefix, String key, String corpid, Integer time, String defaultValue) {
        String value = paasRedisHelper.getValue(prefix, key);
        if (StringUtil.isEmpty(value)) {
            CompanyConfigEntity companyConfigEntity = getByConfigAlias(configAlias, corpid);
            if (Objects.nonNull(companyConfigEntity)) {
                paasRedisHelper.setValue(prefix, key, companyConfigEntity.getConfigValue(), time);
                return companyConfigEntity.getConfigValue();
            } else {
                paasRedisHelper.setValue(prefix, key, defaultValue, time);
                return defaultValue;
            }
        }
        return value;
    }

    @Override
    public List<CompanyConfigEntity> getByAliasAllCompany4Script(String configAlias) {
        return companyConfigDao.getByAliasAllCompany4Script(configAlias);
    }

    @Override
    public List<CompanyConfigEntity> findEntitys(Map<String, Object> param) {
        return companyConfigDao.findEntitys(param);
    }

    @Override
    public List<CompanyConfigEntity> findEntityList(Map<String, Object> param) {
        return companyConfigDao.findEntityList(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return companyConfigDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public Map<String, String> getConfigValueMap(String corpid, List<String> aliasList) {

        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        map.put("configAliasIn", aliasList);
        map.put("columns", "config_alias,config_value");
        List<CompanyConfigEntity> entityList = companyConfigDao.findEntityList(map);
        Map<String, String> valueMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (CompanyConfigEntity entity : entityList) {
            valueMap.put(entity.getConfigAlias(), entity.getConfigValue());
        }
        return valueMap;
    }


    @Override
    public CompanyConfigEntity initConfigEntity(String corpId, String configAlias) throws XbbException {

        CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(configAlias);
        if (configEnum == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, "无此公司配置");
        }

        Map<String, Object> param = new HashMap<>(16);
        param.put("corpid", corpId);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("configAlias", configAlias);

        CompanyConfigEntity config;
        List<CompanyConfigEntity> list = findEntitys(param);
        if (list.size() > 0) {
            // 数据库有该条配置，则获取
            config = list.get(0);
            return config;
        }

        // 如果数据库还没有，说明该公司还未设置，则插入一条默认配置
        config = new CompanyConfigEntity(corpId, configEnum.getName(), configAlias, configEnum.getValue());
        insert(config);
        return config;
    }

    @Override
    public int getFiscalStartMonth(String corpId) {
        int startMonth;
        try {
            CompanyConfigEntity configEntity = initConfigEntity(corpId, CompanyConfigEnum.FISCAL_YEAR.getAlias());
            startMonth = Integer.parseInt(configEntity.getConfigValue());
        } catch (XbbException | NumberFormatException e) {
            startMonth = 1;
        }
        return startMonth;
    }

    @Override
    public CompanyConfigEntity setFiscalStartMonth(String corpId, Integer startMonth) throws XbbException {
        if (startMonth == null || startMonth < BasicConstant.MIN_MONTH || startMonth > BasicConstant.MAX_MONTH) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, "传入的月份不存在");
        }

        CompanyConfigEntity configEntity = initConfigEntity(corpId, CompanyConfigEnum.FISCAL_YEAR.getAlias());
        configEntity.setConfigValue(startMonth.toString());
        update(configEntity);
        return configEntity;
    }


    @Override
    public boolean hasBeenEnable(String corpId, String configAlias, String configValue) throws XbbException {
        CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(configAlias);
        if (configEnum == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, "无此公司配置");
        }

        CompanyConfigEntity entity;
        Map<String, Object> param = new HashMap<>(16);
        param.put("corpid", corpId);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("configAlias", configAlias);
        List<CompanyConfigEntity> list = findEntitys(param);
        if (list.isEmpty()) {
            return false;
        }
        entity = list.get(0);
        return Objects.equals(entity.getConfigValue(), configValue);
    }

    @Override
    public Double getWorkingDayMonth(String corpId) {
        Double workDays;
        try {
            CompanyConfigEntity configEntity = initConfigEntity(corpId, CompanyConfigEnum.WORKING_DAY_MONTH.getAlias());
            workDays = Double.parseDouble(configEntity.getConfigValue());
        } catch (XbbException | NumberFormatException e) {
            workDays = Double.parseDouble(CompanyConfigEnum.WORKING_DAY_MONTH.getValue());
        }
        return workDays;
    }

    @Override
    public Double getWorkingDayWeek(String corpId) {
        Double workDays;
        try {
            CompanyConfigEntity configEntity = initConfigEntity(corpId, CompanyConfigEnum.WORKING_DAY_WEEK.getAlias());
            workDays = Double.parseDouble(configEntity.getConfigValue());
        } catch (XbbException | NumberFormatException e) {
            workDays = Double.parseDouble(CompanyConfigEnum.WORKING_DAY_WEEK.getValue());
        }
        return workDays;
    }

    /**
     * 获取某一个配置 比如移动端设置个人业绩目标权限，or目标配置
     * 1. 对于“移动端设置个人业绩目标权限”，为null则默认有权限 configValue = 1
     * 2. 对于“目标配置”，为null则默认开启所有指标，从枚举PerformanceTypeEnum内获取出所有Index即可
     *
     * @param corpid
     * @param configAlias 通过枚举获取 比如 CompanyConfigEnum.PERFORMANCE_SET.getAlias()，CompanyConfigEnum.PERFORMANCE_TYPES.getAlias()
     * @return
     * @author chuanpeng.zhang
     * @time 2016-8-20 下午3:56:05
     */
    @Override
    public CompanyConfigEntity getConfigEntity(String corpid, String configAlias) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("configAlias", configAlias);

        List<CompanyConfigEntity> list = findEntitys(param);
        if (list != null && list.size() > 0) {
            //数据库有该条配置，则获取
            return list.get(0);
        }

        return null;
    }

    @Override
    public void updateBatch(List<CompanyConfigEntity> updateUserConfigList, String corpid) {
        companyConfigDao.updateBatch(updateUserConfigList, corpid);
    }

    @Override
    public boolean getDuplicateShowRule(String corpid, Integer type) {
        String checkValue = null;
        boolean isCheck = false;
        String configAlias = "";
        if(type == 1){
            //客户查重处是否允许抢
            //默认允许
            isCheck = true;
            configAlias = CompanyConfigEnum.CHECKISGRAB.getAlias();
        }else if(type == 2){
            //客户查重处是否允许加入团队操作
            //默认不允许
            isCheck = false;
            configAlias = CompanyConfigEnum.CHECKISADDTEAM.getAlias();
        }


        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("configAlias",configAlias);

        List<CompanyConfigEntity> checkList = findEntitys(param);
        if (checkList != null && checkList.size() > 0) {
            CompanyConfigEntity check = checkList.get(0);
            if(check!=null){
                checkValue = check.getConfigValue();
            }
        }

        if(type == 1){
            if(checkValue != null && "0".equals(checkValue)){
                //存在设置且值为0，表示不允许
                isCheck = false;
            }else{
                isCheck = true;
            }
        }else if(type == 2){
            if(checkValue != null && "1".equals(checkValue)){
                //存在设置且值为1，表示允许
                isCheck = true;
            }else{
                isCheck = false;
            }

        }

        return isCheck;
    }

    @Override
    public void updateBatch4Script(List<CompanyConfigEntity> companyConfigEntityList) {
        companyConfigDao.updateBatch4Script(companyConfigEntityList);
    }

    /**
     * 获取公司级配置中的最大id
     *
     * @param param
     * @return
     */
    @Override
    public Long getMaxId(Map<String, Object> param) {
        return companyConfigDao.getMaxId(param);
    }

    @Override
    public Boolean getBatchShelf(String corpid) {
        CompanyConfigEntity companyConfigEntity = getByConfigAlias(CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return false;
        }
        return StringUtil.toInt(companyConfigEntity.getConfigValue(), 1) == 1;
    }

    @Override
    public Boolean getSeqManagement(String corpid) {
        CompanyConfigEntity companyConfigEntity = getByConfigAlias(CompanyConfigEnum.ENABLE_SEQ_MANAGEMENT.getAlias(), corpid);
        if (Objects.isNull(companyConfigEntity)) {
            return false;
        }
        return StringUtil.toInt(companyConfigEntity.getConfigValue(), 1) == 1;
    }

    @Override
    public List<String> getByAliasAllCorpids(String configAlias) {
        return companyConfigDao.getByAliasAllCorpids(configAlias);
    }

    @Override
    public Integer deleteBatchByCorpids4Script(List<String> list, String configAlias) {
        return companyConfigDao.deleteBatchByCorpids4Script(list,configAlias);
    }

    @Override
    public Integer hasBeenEnable(String corpid, String alias) throws XbbException {
        CompanyConfigEntity configEntity = initConfigEntity(corpid, alias);

        Integer enable;
        if (configEntity != null) {
            enable = (StringConstant.POSITIVE_NUMBER.equals(configEntity.getConfigValue())) ? BasicConstant.IS_USE : BasicConstant.NO_USE;
        } else {
            CompanyConfigEnum configEnum = CompanyConfigEnum.getByAlias(alias);
            if (configEnum == null) {
                enable = BasicConstant.NO_USE;
            } else {
                try {
                    enable = Integer.parseInt(configEnum.getValue());
                } catch (NumberFormatException e) {
                    enable = BasicConstant.NO_USE;
                }
            }
        }
        return enable;
    }

    /**
     * 需要处理的有工作流并且有paas表单的公司！切忌只为了刷脚本使用，其它情况误使用
     *
     * @return
     */
    @Override
    public List<String> getPaasAndWorkflowCorpList() {
        return companyConfigDao.getPaasAndWorkflowCorpList();
    }

    @Override
    public Integer updateBatchDelByConfigAlias(Integer del, String corpid, List configAliasList) {
        if (CollectionsUtil.isNotEmpty(configAliasList)) {
            return companyConfigDao.updateBatchDelByConfigAlias(del, corpid,configAliasList);
        }
        return null;
    }
}

